#include "dataexporter.h"
#include <QFile>
#include <QTextStream>
#include <QSqlTableModel>
#include <QSqlQueryModel>
#include <QSqlRecord>
#include <QSqlField>
#include <QVariant>
#include <QDateTime>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QXmlStreamWriter>
#include <QMessageBox>

DataExporter::DataExporter(QObject *parent)
    : QObject(parent)
{
}

bool DataExporter::exportTable(QSqlTableModel *model, const QString &filename, ExportFormat format)
{
    if (!model) {
        emit exportError(tr("Invalid model"));
        return false;
    }
    
    bool result = false;
    switch (format) {
    case CSV:
        result = exportToCSV(model, filename);
        break;
    case JSON:
        result = exportToJSON(model, filename);
        break;
    case XML:
        result = exportToXML(model, filename);
        break;
    case SQL:
        result = exportToSQL(model, filename);
        break;
    default:
        emit exportError(tr("Unsupported export format"));
        return false;
    }
    
    if (result) {
        emit exportFinished(tr("Data exported successfully to %1").arg(filename));
    } else {
        emit exportError(tr("Failed to export data to %1").arg(filename));
    }
    
    return result;
}

bool DataExporter::exportQueryResults(QSqlQueryModel *model, const QString &filename, ExportFormat format)
{
    if (!model) {
        emit exportError(tr("Invalid model"));
        return false;
    }
    
    bool result = false;
    switch (format) {
    case CSV:
        result = exportQueryToCSV(model, filename);
        break;
    case JSON:
        result = exportQueryToJSON(model, filename);
        break;
    case XML:
        result = exportQueryToXML(model, filename);
        break;
    case SQL:
        result = exportQueryToSQL(model, filename);
        break;
    default:
        emit exportError(tr("Unsupported export format"));
        return false;
    }
    
    if (result) {
        emit exportFinished(tr("Query results exported successfully to %1").arg(filename));
    } else {
        emit exportError(tr("Failed to export query results to %1").arg(filename));
    }
    
    return result;
}

bool DataExporter::exportToCSV(QSqlTableModel *model, const QString &filename)
{
    QFile file(filename);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        return false;
    }
    
    QTextStream out(&file);
    
    // 写入表头
    QSqlRecord record = model->record();
    for (int i = 0; i < record.count(); ++i) {
        out << escapeCSVField(record.fieldName(i));
        if (i < record.count() - 1) {
            out << ",";
        }
    }
    out << "\n";
    
    // 写入数据行
    for (int row = 0; row < model->rowCount(); ++row) {
        emit exportProgress((row * 100) / model->rowCount());
        
        for (int col = 0; col < record.count(); ++col) {
            QModelIndex index = model->index(row, col);
            QVariant value = model->data(index);
            out << escapeCSVField(value.toString());
            if (col < record.count() - 1) {
                out << ",";
            }
        }
        out << "\n";
    }
    
    file.close();
    return true;
}

bool DataExporter::exportToJSON(QSqlTableModel *model, const QString &filename)
{
    QJsonArray jsonArray;
    
    QSqlRecord record = model->record();
    
    // 添加数据行
    for (int row = 0; row < model->rowCount(); ++row) {
        emit exportProgress((row * 100) / model->rowCount());
        
        QJsonObject rowObject;
        for (int col = 0; col < record.count(); ++col) {
            QModelIndex index = model->index(row, col);
            QVariant value = model->data(index);
            rowObject[record.fieldName(col)] = value.toString();
        }
        jsonArray.append(rowObject);
    }
    
    QJsonDocument doc(jsonArray);
    
    QFile file(filename);
    if (!file.open(QIODevice::WriteOnly)) {
        return false;
    }
    
    file.write(doc.toJson());
    file.close();
    return true;
}

bool DataExporter::exportToXML(QSqlTableModel *model, const QString &filename)
{
    QFile file(filename);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        return false;
    }
    
    QXmlStreamWriter xmlWriter(&file);
    xmlWriter.setAutoFormatting(true);
    xmlWriter.writeStartDocument();
    xmlWriter.writeStartElement("table");
    
    QSqlRecord record = model->record();
    
    // 写入数据行
    for (int row = 0; row < model->rowCount(); ++row) {
        emit exportProgress((row * 100) / model->rowCount());
        
        xmlWriter.writeStartElement("row");
        xmlWriter.writeAttribute("id", QString::number(row));
        
        for (int col = 0; col < record.count(); ++col) {
            QModelIndex index = model->index(row, col);
            QVariant value = model->data(index);
            xmlWriter.writeTextElement(record.fieldName(col), value.toString());
        }
        
        xmlWriter.writeEndElement(); // row
    }
    
    xmlWriter.writeEndElement(); // table
    xmlWriter.writeEndDocument();
    
    file.close();
    return true;
}

bool DataExporter::exportToSQL(QSqlTableModel *model, const QString &filename)
{
    QFile file(filename);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        return false;
    }
    
    QTextStream out(&file);
    
    QString tableName = model->tableName();
    QSqlRecord record = model->record();
    
    // 为每一行生成INSERT语句
    for (int row = 0; row < model->rowCount(); ++row) {
        emit exportProgress((row * 100) / model->rowCount());
        
        out << "INSERT INTO " << tableName << " (";
        
        // 列名
        for (int col = 0; col < record.count(); ++col) {
            out << record.fieldName(col);
            if (col < record.count() - 1) {
                out << ", ";
            }
        }
        
        out << ") VALUES (";
        
        // 值
        for (int col = 0; col < record.count(); ++col) {
            QModelIndex index = model->index(row, col);
            QVariant value = model->data(index);
            
            if (value.isNull()) {
                out << "NULL";
            } else {
                // 根据数据类型处理值
                switch (value.typeId()) {
                case QMetaType::QString:
                case QMetaType::QDateTime:
                case QMetaType::QDate:
                case QMetaType::QTime:
                    out << "'" << value.toString().replace("'", "''") << "'";
                    break;
                default:
                    out << value.toString();
                    break;
                }
            }
            
            if (col < record.count() - 1) {
                out << ", ";
            }
        }
        
        out << ");\n";
    }
    
    file.close();
    return true;
}

bool DataExporter::exportQueryToCSV(QSqlQueryModel *model, const QString &filename)
{
    QFile file(filename);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        return false;
    }
    
    QTextStream out(&file);
    
    // 写入表头
    for (int i = 0; i < model->columnCount(); ++i) {
        out << escapeCSVField(model->headerData(i, Qt::Horizontal).toString());
        if (i < model->columnCount() - 1) {
            out << ",";
        }
    }
    out << "\n";
    
    // 写入数据行
    for (int row = 0; row < model->rowCount(); ++row) {
        emit exportProgress((row * 100) / model->rowCount());
        
        for (int col = 0; col < model->columnCount(); ++col) {
            QModelIndex index = model->index(row, col);
            QVariant value = model->data(index);
            out << escapeCSVField(value.toString());
            if (col < model->columnCount() - 1) {
                out << ",";
            }
        }
        out << "\n";
    }
    
    file.close();
    return true;
}

bool DataExporter::exportQueryToJSON(QSqlQueryModel *model, const QString &filename)
{
    QJsonArray jsonArray;
    
    // 添加数据行
    for (int row = 0; row < model->rowCount(); ++row) {
        emit exportProgress((row * 100) / model->rowCount());
        
        QJsonObject rowObject;
        for (int col = 0; col < model->columnCount(); ++col) {
            QModelIndex index = model->index(row, col);
            QVariant value = model->data(index);
            QString header = model->headerData(col, Qt::Horizontal).toString();
            rowObject[header] = value.toString();
        }
        jsonArray.append(rowObject);
    }
    
    QJsonDocument doc(jsonArray);
    
    QFile file(filename);
    if (!file.open(QIODevice::WriteOnly)) {
        return false;
    }
    
    file.write(doc.toJson());
    file.close();
    return true;
}

bool DataExporter::exportQueryToXML(QSqlQueryModel *model, const QString &filename)
{
    QFile file(filename);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        return false;
    }
    
    QXmlStreamWriter xmlWriter(&file);
    xmlWriter.setAutoFormatting(true);
    xmlWriter.writeStartDocument();
    xmlWriter.writeStartElement("query_results");
    
    // 写入数据行
    for (int row = 0; row < model->rowCount(); ++row) {
        emit exportProgress((row * 100) / model->rowCount());
        
        xmlWriter.writeStartElement("row");
        xmlWriter.writeAttribute("id", QString::number(row));
        
        for (int col = 0; col < model->columnCount(); ++col) {
            QModelIndex index = model->index(row, col);
            QVariant value = model->data(index);
            QString header = model->headerData(col, Qt::Horizontal).toString();
            xmlWriter.writeTextElement(header, value.toString());
        }
        
        xmlWriter.writeEndElement(); // row
    }
    
    xmlWriter.writeEndElement(); // query_results
    xmlWriter.writeEndDocument();
    
    file.close();
    return true;
}

bool DataExporter::exportQueryToSQL(QSqlQueryModel *model, const QString &filename)
{
    QFile file(filename);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        return false;
    }
    
    QTextStream out(&file);
    out << "-- Query results export\n";
    
    // 为每一行生成INSERT语句（使用虚拟表名）
    for (int row = 0; row < model->rowCount(); ++row) {
        emit exportProgress((row * 100) / model->rowCount());
        
        out << "INSERT INTO query_results (";
        
        // 列名
        for (int col = 0; col < model->columnCount(); ++col) {
            QString header = model->headerData(col, Qt::Horizontal).toString();
            out << header;
            if (col < model->columnCount() - 1) {
                out << ", ";
            }
        }
        
        out << ") VALUES (";
        
        // 值
        for (int col = 0; col < model->columnCount(); ++col) {
            QModelIndex index = model->index(row, col);
            QVariant value = model->data(index);
            
            if (value.isNull()) {
                out << "NULL";
            } else {
                // 根据数据类型处理值
                switch (value.typeId()) {
                case QMetaType::QString:
                case QMetaType::QDateTime:
                case QMetaType::QDate:
                case QMetaType::QTime:
                    out << "'" << value.toString().replace("'", "''") << "'";
                    break;
                default:
                    out << value.toString();
                    break;
                }
            }
            
            if (col < model->columnCount() - 1) {
                out << ", ";
            }
        }
        
        out << ");\n";
    }
    
    file.close();
    return true;
}

QString DataExporter::escapeCSVField(const QString &field) const
{
    if (field.contains(',') || field.contains('"') || field.contains('\n')) {
        QString escaped = field;
        escaped.replace('"', "\"\"");
        return "\"" + escaped + "\"";
    }
    return field;
}